Journal

2009-03-19

Text search setup for several languages

There are several ways - below is one common setup.

Assuming you know language, text search setup can be easy. Below is an example for english-russian text collection.

postgres=# create table inttext ( lang regconfig, doc text);
CREATE TABLE
Time: 760.216 ms
postgres=# insert into inttext values('russian','голубые дали');
INSERT 0 1
Time: 365.939 ms
postgres=# insert into inttext values('english','hazy distance');
INSERT 0 1
Time: 363.096 ms
postgres=# select to_tsvector(lang,doc) from inttext;
     to_tsvector
----------------------
 'голуб':1 'дал':2
 'distanc':2 'hazi':1
(2 rows)

Of course, instead of built-in text search configurations you can use your very own.

Another alternatives are:

0 Comments on this page

2009-03-14

CSV output

Надо было сделать подвыборку не всех полей из большой БД, оказалось очень просто можно сделать так:

psql -t cas -c 'copy ( 
select id, ra,dec, pm_ra, pm_dec, bmag, vmag, rmag from nomad.main 
where vmag >= 5 and vmag <=17
                      ) 
to stdout with csv' > nomad-x-5-17.csv

0 Comments on this page

2009-03-13

New cool text search features for 8.4+

  • We added support of filtering dictionaries Contrary to standard behaviour output from filtering dictionary is always passes to the next dictionary (if any), which allows useful lexeme preprocessing, for example, remove accents without any issues in ts_headline() function.
  • unaccent dictionary/function. Uses suffix tree for performance (about 25 times faster than variant with built-in translate() function).
  • Add prefix search support to the synonym dictionary. Star sign '*' at the end of definition word indicates, that definition word is a prefix and to_tsquery() function will transform that definition to the prefix search format. Notice, it is ignored in to_tsvector().
> cat $SHAREDIR/tsearch_data/synonym_sample.syn
postgres        pgsql
postgresql      pgsql
postgre pgsql
gogle   googl
indices index*

=# create text search dictionary syn( template=synonym,synonyms='synonym_sample');
=# select ts_lexize('syn','indices');
 ts_lexize
-----------
 {index}
(1 row)
=# create text search configuration tst ( copy=simple);
=# alter text search configuration tst alter mapping for asciiword with syn;
=# select to_tsquery('tst','indices');
 to_tsquery
------------
 'index':*
(1 row)
=# select 'indexes are very useful'::tsvector @@ to_tsquery('tst','indices');
 ?column?
----------
 t
(1 row)

=# select to_tsvector('tst','indices');
 to_tsvector
-------------
 'index':1
(1 row)


0 Comments on this page

2009-02-26

Nepali support for text search !

Looks like we (Oleg Bartunov, Teodor Sigaev) did first working patch for nepali language (Devanagari script) support in text search ! We introduced Virama/Halanta support and Spacing Combining category. A lot of Unicode documents readings :)

Thanks to Dibyendra Hyoju and Bal Krishna Bal for testing and valuable discussion !

postgres=# set client_encoding to UTF8;
SET
Time: 0.119 ms
postgres=# select * from ts_parse('default','मदन पुरस्कार पुस्तकालय');
 tokid |  token  
-------+---------
     2 | मदन
    12 |  
     2 | पुरस्कार
    12 |  
     2 | पुस्तकालय
(5 rows)

'मदन पुरस्कार पुस्तकालय' - Madan Puraskar Pustakalaya, name of an entity

This looks pretty trivial, but actually it was not easy. Below is the the same string, displayed using uniname program. Notice, DEVANAGARI SIGN VIRAMA and DEVANAGARI VOWEL SIGNs, they are listed as punct in locale and should break words, which would be wrong !

character  byte       UTF-32   encoded as     glyph   name
        0          0  00092E   E0 A4 AE       म      DEVANAGARI LETTER MA
        1          3  000926   E0 A4 A6       द      DEVANAGARI LETTER DA
        2          6  000928   E0 A4 A8       न      DEVANAGARI LETTER NA
        3          9  000020   20                     SPACE
        4         10  00092A   E0 A4 AA       प      DEVANAGARI LETTER PA
        5         13  000941   E0 A5 81       ु      DEVANAGARI VOWEL SIGN U
        6         16  000930   E0 A4 B0       र      DEVANAGARI LETTER RA
        7         19  000938   E0 A4 B8       स      DEVANAGARI LETTER SA
        8         22  00094D   E0 A5 8D       ्      DEVANAGARI SIGN VIRAMA
        9         25  000915   E0 A4 95       क      DEVANAGARI LETTER KA
       10         28  00093E   E0 A4 BE       ा      DEVANAGARI VOWEL SIGN AA
       11         31  000930   E0 A4 B0       र      DEVANAGARI LETTER RA
       12         34  000020   20                     SPACE
       13         35  00092A   E0 A4 AA       प      DEVANAGARI LETTER PA
       14         38  000941   E0 A5 81       ु      DEVANAGARI VOWEL SIGN U
       15         41  000938   E0 A4 B8       स      DEVANAGARI LETTER SA
       16         44  00094D   E0 A5 8D       ्      DEVANAGARI SIGN VIRAMA
       17         47  000924   E0 A4 A4       त      DEVANAGARI LETTER TA
       18         50  000915   E0 A4 95       क      DEVANAGARI LETTER KA
       19         53  00093E   E0 A4 BE       ा      DEVANAGARI VOWEL SIGN AA
       20         56  000932   E0 A4 B2       ल      DEVANAGARI LETTER LA
       21         59  00092F   E0 A4 AF       य      DEVANAGARI LETTER YA

Next step is to port nepali stemmer, so we can provide default text search configuration for nepali.

Also, we need to improve hunspell support, so nepali ispell dictionaries can be used with text search !

This project is a volunteer work to support PostgreSQL promotion in Nepal (btw, elephants are there). I will visit Nepal this april and will establish more close connections with nepali developers.

0 Comments on this page

2009-02-14

pg_reorg - кластеризация таблицы в онлайне !

Всем известно, что кластеризация таблицы по индексу может дать очень большой выигрыш за счет меньшего количества позиционирования головки диска. Особенно это хорошо для read-only таблиц, для которых раз сделанная кластеризация (clusterdb, CLUSTER …) сохраняет свои хорошие качества. Для изменяющихся данных приходится кластеризовать время от времени, что достаточно мучительно, ибо не только медленно, но и из-за лока на таблицу. И тут рулит pg_reorg, еще одно творение клевых парней из NTT. Вот краткая выжимка из документации

pg_reorg is an utility program to reorganize tables in PostgreSQL 
databases. Unlike clusterdb, it doesn't block any selections and 
updates during reorganization. You can choose one of the following 
methods to reorganize.

    * Online CLUSTER (ordered by cluster index)
    * Ordered by specified columns
    * Online VACUUM FULL (packing rows only)

NOTICE:

    * Only superusers can use the utility.
    * Target table must have PRIMARY KEY.
    * You'd better to do ANALYZE after pg_reorg is completed.

И без перевода понятно насколько это полезная утилита ! Узнал про это я из интересной статьи Cluster data, save cash.

0 Comments on this page

2009-01-17

Пик Советов

Наткнулся на страничку калмыка (?) http://www.flat.ru/kalmyk/kazakh/treks/sovet.htm про Пик Советов (4300 м), на который я ходил 2 раза - еще в августе 1986 годах. На этой страничке показан маршрут, которым я с Костей Постновым, Володей Самодуровым, Юрой Шинтарем и Леной Путилиной поднялись на пик Советов, будучи в стройотряде на Алма-Атинской Высокогорной станции ГАИШ, когда пережидали сель, который снес дорогу и наши строительные работы на этом благополучно закончились. Помню, что Акрем обещался наблюдать за нами через Цейсс-600 :) Устали тогда умеренно, разве что обгорели прилично. Вниз спускались очень быстро по сыпуну по очереди, тогда моим чешским вибрамам пришел долгожданный конец. Осталось только несколько слайдов с тех времен.

Второй раз - в 1991 году с Женей Семеновым, Колей Симоновым и его дочерью Дашей (6-7 лет ?). Коля и Даша на вершину не пошли, а я с Семеновым благополучно взобрались по самому кратчайшему маршруту весьма резво, причем я был за оператора и снимал все на камеру Сони (куда жа пленка делась ?), приходилось скакать вверх и вниз, чтобы выбрать хороший план. Кстати, где-то внизу остался Вася Сафрошкин и Кира (другая), почему они не пошли в гору я не помню. Зато прекрасно помню, что в это утро в Москве случился путч и мы с Семеновым прямо на вершине выразили свое негодование (несколько неприличным способом) глядя почему-то на Китай.

Интересно, что никакой горной болезни ни разу ни у кого обнаружено не было, хотя высоту (c 2000 до 4300) набирали за несколько часов. Правда, мы до этого жили на высоте > 2000 м. И на горе Майданак (военной) играли в волейбол на высоте 2700 м, помнится солдаты в оцеплении стояли, чтобы мяч далеко вниз не укатился :) Совсем недавно за пару часов забежали от БТА до вершины горы Пастухова (2700 м), только ноги намочили от ранней росы (вышли в 4 утра). Мне это интересно, так как в апреле я собираюсь в Непал прогуляться вокруг Анапурны (максимум 5400 м), посмотреть на самое высокогорное озеро Тиличо (Tilicho) ( ~5000 м).

0 Comments on this page

2009-01-11

Развитие СУБД PostgreSQL в 2008 году

Олег Бартунов, Федор Сигаев

GIN - Generalized Inverted Index
Алгоритм быстрой вставки в обратный индекс - известно, что обновление обратного индекса является "тяжелой" операцией, которая, тем не менее, востребована в задачах оперативного обновления данных. Например, добавление только одной небольшой статьи, которая содержит 100 уникальных слов, вызовет 100 обновлений обратного индекса, что при условии соблюдения целостности и безопасности данных (ACID) является дорогостоящей операцией. Алгоритм предполагает хранение новых записей вне индекса, и добавление их во время работы сборщика статистики (vacuum analyze). При этом выигрыш достигается за счет использования буфера памяти для накапливания обратных списков, которые сбрасываются на диск за один раз по мере заполнения буфера. Стоит отметить, что поиск продолжает работать корректно, но несколько медленнее, из-за необходимости последовательного чтения записей вне индекса. При создании индекса можно указать использовать или нет алгоритм ускоренной вставки.
Алгоритм поиска на частичное соответствие (partial match). Предыдущие версии обратного индекса GIN поддерживали поиск только по точному совпадению ключей,в то время как новый алгоритм реализует поиск ключей по префиксу.
Поддержка композитных индексов, т.е. индексов, которые поддерживают комбинацию атрибутов. В PostgreSQL такую поддержку имеют Btree и GiST индексы, однако, эффективность GIN индекса не зависит от того, по какому атрибуту производится поиск, что позволяет использовать один индекс как для поиска по комбинации атрибутов, так и по отдельным атрибутам.
GiST - Generalized Search Tree
Поддержка новых версий и исправление ошибок
Full-text search
Улучшение поиска с ограничением по весу лексем. Обратный индекс не содержит никаких метаданных, поэтому результаты поиска необходимо проверить на соответствие дополнительным ограничениям, если они были заданы в поисковом запросе. Для этого использовался специальный оператор, который не нес никакой дополнительной семантики и перегружал пользовательский интерфейс. Благодаря улучшениям в ядре PostgreSQL удалось избавиться от лишнего оператора.
Поддержка префиксного поиска в полнотекстовом поиске с индексной поддержкой GIN. Благодаря поддержке в обратном индексе поиска на частичное соответствие стало возможным использовать в полнотекстовом поиске шаблонов.
Разработана алгебра полнотекстовых запросов, которая необходима для корректного поиска по фразам (phrase search). В богатый язык запросов полнотекстового поиска (операторы AND, OR, AND NOT, группировка) добавлен оператор, который гарантирует порядок следования операндов и расстояние (в словах) между ними.
Расширения PostgreSQL
wildspeed - индексная (GIN) поддержка поиска подстрок для SQL оператора LIKE, например, '%text%'. Эта реализация использует алгоритм поиска на частичное соответствие GIN.
unaccent - расширение, которое убирает диакритические знаки, используемые во многих европейских языках. Использование суффиксного дерева и кэширования позволило в десятки раз ускорить операцию по сравнению со встроенной функцией translate. Актуальность расширения определяется необходимостью убирать диакритические знаки из текста перед полнотекстовым поиском (индексация и поиск) для получения однозначных результатов.
btree_gin - реализация B-tree с использованием GIN. Модуль поддерживает практические все основные типы данных, используемые в PostgreSQL и позволяет создавать композитные индексы, так как PostgreSQL не поддерживает создание индексов с использованием разных AM (методов доступа), например, GIN и btree. Наиболее популярный метод доступа - btree поддерживает все основные типы данных, поэтому его эмуляция с помощью GIN, позволяет создавать композитные индексы GIN не только для множеств (для которых GIN и создавался), но и для всех основных типов данных, например, индекс по (timestamp, tsvector) будет ускорять полнотекстовый поиск с ограниченим по дате.
gevel - добавлена поддержка GIN индексов, быстрая приближенная статистика. Это расширение используется как инструмент для изучения и разработки новых индексов на основе GiST, GIN.
varbit - индексная поддержка (GiST, GIN) операций (overlap, contains, contained) для типа varbit. Одним из примеров эффективного использования является поиск по флагам, реализованных как тип varbit, для которых стандартный Btree индекс неэффективен из-за малой мощности множества значений (обычно, это 0 или 1).
pg_trgm - поддержка многобайтных кодировок, в частности, UTF-8. Это расширение реализует поиск похожих строк на основе статистики триграм, а также может использоваться в сочетании с полнотекстовым поиском для поиска с ошибками. Замечательной особенностью этого подхода является независимость от языка.
ltree - поддержка многобайтных кодировок, в частности, UTF-8. Это расширение используется для индексной поддержки операций с иерархическими данными.

Описанные работы по системам разработки расширений GIN, GiST, полнотекстовому поиску вошли в ядро СУБД PostgreSQL и будут доступны для публичного использования, начиная с версии 8.4, намеченное на первый квартал 2009 года. Большинство расширений также входит в состав дистрибутива PostgreSQL.

Часть результатов была доложена на ежегодной конференции разработчиков PostgreSQL - http://www.pgcon.org/2008/schedule/events/58.en.html, на конференции "Научный сервис в сети Интернет- 2008" http://agora.guru.ru/display.php?conf=abrau2008&page=item011, на конференции "PgDay-2008", Oct 17-18, 2008, Prato, Italy (http://wiki.postgresql.org/wiki/European_PGDay_2008)

0 Comments on this page

2008-12-30

Window function in the CVS HEAD (8.4) !

Window function (SQL 2003) - one of the very interesting for OLAP feature previously missed in PostgreSQL was committed to the CVS HEAD by Tom Lane. Hitoshi Harada wrote proposal and made a patch, see his site for more details. There was no support for user-defined window function, but Tom believe, that 8.4 should have it. Very good.

Simply speaking, window function is an aggregate over a partitioned set of rows. Think about window moving over rows.

One of the interesting application of window function would be data smoothing.

0 Comments on this page

2008-12-19

Toulouse - Lourdes - Gavarnie - St.Jean Pied de Port - Orreaga/Roncesvalles - Biarritz - Toulouse

Weekend at Pyrenees, 860 km driving. The song of Roland, Charlemagne, The Pilgrims Cross, El Camino de Santiago.

No people, no restaurants, no hotels, a lot of cleanest air, whitest snow and romantic. The ocean was stormy, so no swimming, but again, very nice view on waves suddenly appearing in the ocean.

Lourdes was empty, the holy water was freshe, the basilica was nice

Conclusion: Return to Pyrenee at spring/summer time

0 Comments on this page

2008-12-17

Getting words from tsvector

Sometimes it's needed to get indexed words from tsvector. ts_stat() is good, but not convenvient. Function below allows to use ts_stat with tsvector:

CREATE OR REPLACE FUNCTION ts_stat(tsvector, OUT word text, OUT ndoc
integer, OUT nentry integer)
RETURNS SETOF record AS
$$
    SELECT ts_stat('SELECT ' || quote_literal( $1::text ) || '::tsvector');
$$ LANGUAGE SQL RETURNS NULL ON NULL INPUT IMMUTABLE;

Then, you can use it

select id, (ts_stat(fts)).* from apod where id=1;
 id |    word    | ndoc | nentry
----+------------+------+--------
  1 | 1          |    1 |      1
  1 | 2          |    1 |      2
  1 | io         |    1 |      2
  1 | may        |    1 |      1
  1 | new        |    1 |      1
  1 | red        |    1 |      1
  1 | two        |    1 |      1
  1 | 1979       |    1 |      2
  1 | 1996       |    1 |      1
  1 | 27th       |    1 |      1
  1 | also       |    1 |      1

0 Comments on this page

More...